package me.goldze.mvvmhabit.binding.viewadapter.image


import android.app.Activity
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.StateListDrawable
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.chengyi.serialport.demo.utils.PictureSelectorHelp
import com.qmuiteam.qmui.util.QMUIDrawableHelper
import com.wyj.utils.AssetsUtil
import com.wyj.utils.BitmapUtils
import com.wyj.utils.FileUtils
import com.wyj.utils.Utils.isNullOrEmpty
import com.wyj.utils.asActivity
import me.goldze.mvvmhabit.binding.command.BindingCommand
import me.goldze.mvvmhabit.binding.viewadapter.view.ViewAdapter


/**
 * Created by goldze on 2017/6/18.
 */
object ViewAdapter {
    @BindingAdapter(value = ["url", "placeholderRes", "cacheFileName", "previewByClick", "isGif"], requireAll = false)
    @JvmStatic
    fun setImageUri(imageView: ImageView, url: String?, placeholderRes: Any?, cacheFileName: String?, previewByClick: Boolean?, isGif: Boolean?) {
        val url = when {
            //assets文件使用一定要在build.gradle加上
            // sourceSets {
            //        main {
            //            assets {
            //                srcDirs = ["src/main/assets"]
            //            }
            //        }
            //    }
            //如果assets中有资源文件被更新（例如v1.apk和v2.apk都有a.png，但图片不一样）一定要在application中加context.cacheDir?.let { FileUtils.deleteFiles(it) }
            url?.startsWith("@/") == true -> url.replace("^@/".toRegex(), "${AssetsUtil.ROOT}images/")
            //如果raw中有资源文件被更新（例如v1.apk和v2.apk都有a.png，但图片不一样）一定要在application中加context.cacheDir?.let { FileUtils.deleteFiles(it) }
            url?.startsWith("R/") == true -> url.replace("^R/".toRegex(), "android.resource://${imageView.context.packageName}/raw/")
            url?.startsWith("@drawable/") == true -> url.replace("^@drawable/".toRegex(), "android.resource://${imageView.context.packageName}/drawable/")
            else -> url
        }
        val cacheFilePath = if (isNullOrEmpty(cacheFileName)) null else imageView.context.cacheDir.absolutePath + "/cacheImages/" + cacheFileName
        val placeBitmap = cacheFilePath?.let { FileUtils.getBitmapFromFile(it) }
        var placeDrawable = placeBitmap?.let { BitmapUtils.bitmap2Drawable(placeBitmap) }
        if (placeDrawable == null) {
            placeDrawable = when (placeholderRes) {
                is Int -> BitmapUtils.bitmap2Drawable(BitmapFactory.decodeResource(imageView.context.resources, placeholderRes))
                is Drawable -> placeholderRes
                else -> null
            }
        }
        if (!isNullOrEmpty(url)) {
            Glide.with(imageView.context).let {
                (if (isGif == true) it.asGif() else it.asDrawable()) as RequestBuilder<Any>
            }.load(url).let {
                if (placeDrawable != null) it.placeholder(placeDrawable).error(placeDrawable) else it
            }.listener(object : RequestListener<Any> {
                override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Any>, isFirstResource: Boolean): Boolean {
                    return false
                }

                override fun onResourceReady(resource: Any, model: Any, target: Target<Any>?, dataSource: DataSource, isFirstResource: Boolean): Boolean {
                    if(cacheFilePath != null) {
                        when (resource) {
                            is GifDrawable -> {
                                FileUtils.writeFile(resource.buffer, cacheFilePath)
                            }

                            is Drawable -> {
                                FileUtils.writeFile(BitmapUtils.drawable2InputStream(resource), cacheFilePath)
                            }
                        }
                    }
                    return false
                }
            }).into(imageView)
        } else {
            imageView.setImageDrawable(placeDrawable)
        }
        if (previewByClick == true) {
            ViewAdapter.onClickCommand(imageView, BindingCommand { context ->
                val activity=context.asActivity<Activity>()
                if(activity!=null&&url!=null){
                    PictureSelectorHelp.startActivityPreview(activity, url)
                }
            })
        }
    }

    @BindingAdapter(value = ["colorFilter"])
    @JvmStatic
    fun setColorFilter(imageView: ImageView, color: Int) {
        imageView.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY)
    }

    @BindingAdapter(value = ["android:src"])
    @JvmStatic
    fun setSrc(imageView: ImageView, src: Any) {
        when (src) {
            is Int -> imageView.setImageResource(src)
            is Drawable -> imageView.setImageDrawable(src)
            is Bitmap -> imageView.setImageBitmap(src)
        }
    }

    @BindingAdapter(value = ["android:src", "normalColorFilter", "selectorColorFilter"], requireAll = true)
    @JvmStatic
    fun setSelectorColorFilter(imageView: ImageView, src: Any, normalColor: Int, selectorColor: Int) {
        (when (src) {
            is Int -> ContextCompat.getDrawable(imageView.context, src)
            is Drawable -> src
            else -> null
        })?.let { drawable ->
            QMUIDrawableHelper.drawableToBitmap(drawable)?.let {
                val newDrawable = BitmapDrawable(imageView.context.resources, it)
                newDrawable.colorFilter = PorterDuffColorFilter(selectorColor, PorterDuff.Mode.MULTIPLY)
                drawable.colorFilter = PorterDuffColorFilter(normalColor, PorterDuff.Mode.MULTIPLY)
                val selectorDrawable = StateListDrawable()
                selectorDrawable.addState(IntArray(1) { android.R.attr.state_pressed }, newDrawable)
                selectorDrawable.addState(IntArray(1) { android.R.attr.state_selected }, newDrawable)
                selectorDrawable.addState(IntArray(0), drawable)
                imageView.isPressed = true
                imageView.setImageDrawable(selectorDrawable)
            }
        }
    }
}